/**
  ******************************************************************************
  * @file    main.c
  * @author  AE Team
  * @version 1.0.3
  * @date    2024-05-28
  * @brief   演示ATIM通道3比较匹配触发ADC单通道单次转换，转换完成触发EOC中断
  *          转换完成的结果通过UART2.TXD(PB02)发出，115200-8-N-1
  *          请调节电 位 器 RP1 改变ADC_IN6(PA06)端口的电压(0 ~ AVCC)
  *          请使用串口调试助手接收显示串口发送的数据
  *
  * @note    硬件平台：SYM32L010_StartKit_V1.0
  *          接线说明：断开J12
  *                    短接J23,J24,J13,J28
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 SIYIMicro.
  * All rights reserved.</center></h2>
  *
  *
  ******************************************************************************
  */


/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include "main.h"
#include "sym32l010_hal_sysctrl.h"
#include "sym32l010_hal_systick.h"
#include "sym32l010_hal_gpio.h"
#include "sym32l010_hal_adc.h"
#include "sym32l010_hal_atim.h"
#include "sym32l010_startkit_board.h"


/******************************************************************************/
/* Local pre-processor symbols/macros ('#define')                             */
/******************************************************************************/

/******************************************************************************/
/* Global variable definitions (declared in header file with 'extern')        */
/******************************************************************************/
ATIM_HandleTypeDef hatim;
__IO uint8_t gAdcConvFlag;

/******************************************************************************/
/* Local type definitions ('typedef')                                         */
/******************************************************************************/

/******************************************************************************/
/* Local function prototypes ('static')                                       */
/******************************************************************************/
static void ATIM_Init(void);
static void ADC_Init(void);

/******************************************************************************/
/* Local variable definitions ('static')                                      */
/******************************************************************************/

/******************************************************************************/
/* Local pre-processor symbols/macros ('#define')                             */
/******************************************************************************/

/******************************************************************************/
/* Function implementation - global ('extern') and local ('static')           */
/******************************************************************************/


/*******************************************************************************
 ** \brief  Main function of project
 **
 ** \return uint32_t return value, if needed
 **
 **
 ******************************************************************************/
int32_t main(void)
{
    // 配置系统时钟
    HAL_SysCtrl_HSI_SetDiv(HSIOSC_TO_HSI24MHZ);

    // 初始化SysTick
    HAL_InitTick(24000000);

    // 板载UART打印初始化 115200-8-N-1 TXD = PB02
    Bsp_Uart_Init(24000000, 115200);

    // 板载电位器端口初始化
    Bsp_RheostatPort_Init();

    // 板载LED初始化
    Bsp_Led_Init();

    // 初始化ADC
    ADC_Init();

    // 初始化ATIM
    ATIM_Init();

    //------------------------------------------------------------
    // 请调节电 位 器 RP1 改变ADC_IN6(PA06)端口的电压(0 ~ AVCC)
    // 通过板载UART查看ADC转换完成的结果及AdcIn6、BGR1V2 输入的电压值

    uint32_t count = 0;
    uint32_t tmp32 = 0;
    while (1)
    {
        if (gAdcConvFlag)                                             // 每10ms, ATIM触发ADC转换一次
        {
            gAdcConvFlag = 0x00;

            tmp32 += HAL_ADC_Result0_Read();                          // 采样20次取平均值
            if (++count >= 20)
            {
                float    AdcIn = 3.3 * (tmp32 / 20) / 4095;
                printf("AdcCode = 0x%03X    Voltage = %4.3fV\r\n", tmp32/20, AdcIn);
                count = 0;
                tmp32 = 0;
            }
        }
    }
}


/*******************************************************************************
 * @brief  ATIM初始化
 * @param  None
 * @retval None
 */
static void ATIM_Init(void)
{
    GPIO_InitTypeDef      GPIO_InitStruct;
    ATIM_SlaveConfigTypeDef ATIM_SlaveCfgStruct;

    MemClr(&GPIO_InitStruct, sizeof(GPIO_InitStruct));
    MemClr(&ATIM_SlaveCfgStruct, sizeof(ATIM_SlaveCfgStruct));

    // 使能外设时钟
    HAL_SYSCTRL_GPIOA_CLK_ENABLE();
    HAL_SYSCTRL_ATIM_CLK_ENABLE();

    // 配置ATIM管脚
    // 注：IO的翻转会对ADC的采样精度造成干扰，关闭IO的翻转可以提高ADC的采样精度
    //AFx_ATIMCH3_PA03();
    GPIO_InitStruct.Pins = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(SYM_GPIOA, &GPIO_InitStruct);

    // 配置ATIM
    MemClr(&hatim, sizeof(hatim));

    hatim.Instance               = SYM_ATIM;
    hatim.Init.ClockDivision     = ATIM_CLOCKDIVISION_DIV1;
    hatim.Init.CounterMode       = ATIM_COUNTERMODE_UP;
    hatim.Init.Prescaler         = 24000 - 1;
    hatim.Init.Period            = 10 - 1;                            // 溢出周期10ms
    hatim.Init.RepetitionCounter = 0;
    hatim.Init.AutoReloadPreload = ATIM_AUTORELOAD_PRELOAD_DISABLE;
    HAL_ATIM_OC_Init(&hatim);

    // 配置OC输出
    hatim.OcInit.OCMode = ATIM_OCMODE_TOGGLE;                         // 比较匹配翻转
    hatim.OcInit.Pulse  = 5 - 1;
    hatim.OcInit.OCIdleState = ATIM_OCIDLESTATE_SET;
    hatim.OcInit.OCPolarity = ATIM_OCPOLARITY_HIGH;
    HAL_ATIM_OC_ConfigChannel(&hatim, &hatim.OcInit, ATIM_CHANNEL_3);

    HAL_ATIM_OC_Start(&hatim, ATIM_CHANNEL_3);
}


/*******************************************************************************
 * @brief  ADC 初始化函数
 * @param  None
 * @retval None
 *
 */
static void ADC_Init(void)
{
    ADC_InitTypeDef             ADC_InitStruct;
    ADC_SqrInitTypeDef          ADC_SqrInitStruct;

    MemClr(&ADC_InitStruct, sizeof(ADC_InitStruct));
    MemClr(&ADC_SqrInitStruct, sizeof(ADC_SqrInitStruct));

    // 使能外设时钟
    HAL_SYSCTRL_ADC_CLK_ENABLE();

    // 配置 ADC，单次转换模式
    ADC_InitStruct.WorkMode     = ADC_WORKMODE_ONESHOT;               // 单次转换模式
    ADC_InitStruct.ClockSource  = ADC_CLKSRC_DIV1;                    // ADCCLK = PCLK = 24MHz
    ADC_InitStruct.BgrEn        = ADC_BGR_DISABLE;
    ADC_InitStruct.TempSensorEn = ADC_TS_DISABLE;
    HAL_ADC_Init(&ADC_InitStruct);

    HAL_ADC_Enable();                                                 // 使能ADC

    // 通过调用函数实现单通道采样模式
    HAL_ADC_OneSqrChannel_Config(ADC_SQRCH_0, ADC_IN6, ADC_SAMPLE_CLK9); // SQRCH0的模拟输入源选择ADC_IN6, 采样时间为9CLK

    // 配置ADC硬件触发源
    HAL_ADC_Trigger_Config(ADC_TRS_ATIM_CC3);

    HAL_ADC_ENABLE_IT(ADC_IT_SOURCE_EOC);                             // 使能ADC转换完成中断
    NVIC_ClearPendingIRQ(ADC_IRQn);
    NVIC_EnableIRQ(ADC_IRQn);                                         // 使能NVIC.ADC
}


/*******************************************************************************
 * @brief  ADC 中断服务程序回调函数
 * @param  None
 * @retval None
 *
 */
void ADC_IRQHandlerCallBack(void)
{
    if (HAL_ADC_GET_IT_SOURCE(ADC_IT_SOURCE_EOC) && HAL_ADC_GET_FLAG(ADC_IT_FLAG_EOC))
    {
        gAdcConvFlag = 0x01;
        HAL_ADC_CLR_FLAG(ADC_IT_FLAG_EOC);
        //BSP_LED_TOG();
    }
}


/*******************************************************************************
 ** EOF (not truncated)
 ******************************************************************************/
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER CODE BEGIN */
    /* User can add his own implementation to report the file name and line number,
       tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END */
}
#endif /* USE_FULL_ASSERT */


/************************ (C) COPYRIGHT SIYIMicro *****END OF FILE*************/
